/*
 * @(#)SimulationObject.java	28.08.1997 Didier Gutacker
 *
 */

import java.awt.*;
import java.util.Vector;
import java.net.URL;

/** 
 * Die Klasse SimulationObject stellt die Methoden zur Verfuegung, die 
 * von Instanzen der Klasse ArchitecureComponent benoetigt werden
 * Sie ist die Superklasse jeglicher Simulationsobjekte, wie z.B. im
 * vorliegenden Fall dem Netzwerk.
 * 
 * @author       Didier Gutacker
 * @version     1.0, 28.08.1997
 * @see ArchitectureComponent
 * @see Simulation
 * 
 */

public abstract class SimulationObject implements Runnable {

  protected Simulation simulation;

  protected int xOffset = 0;
  protected int yOffset = 0;
  protected Lock offsetChangeLock;

  protected ThreadGroup tg;
  protected Thread remoteThread; 

  protected Vector archComponents;
  protected ArchitectureComponent focussedComponent;
  protected Lock archChangeLock;

  protected boolean finished = false;


  /**
   *  Konstruktor 
   *
   * @see Simulation
   * @see SimulationFrame
   */

  public SimulationObject( Simulation simulation, SimulationFrame frame ) {
    this.simulation = simulation;
     tg = frame.getThreadGroup();
     offsetChangeLock = new Lock();
     archChangeLock = new Lock();
  } // SimulationObject.SimulationObject

  /**
   * Startet den "Client" Betrieb
   * @see SimulationClient
   * @see SimulationServer
   */

  public final void startRemote() {
    remoteThread = new Thread( tg, this );
    remoteThread.start();
  } // SimulationObject.startRemote

  /**
   * Liefert die ThreadGroup in der sich alle hier Threads befinden sollten
   */

  public final ThreadGroup getThreadGroup() {
    return tg;
  } // SimulationObject.getThreadGroup

  /**
   * Setze den Zeichenursprung auf die übergebenen Koordinaten
   * THREADSAFE
   * @see SimulationObject#getXOffset
   * @see SimulationObject#getYOffset
   */

  public final void translate( int x, int y ) {
    offsetChangeLock.acquire();
    xOffset = x;
    yOffset = y;
    offsetChangeLock.release();
  } // SimulationObject.translate

  /**
   * Liefert die x-Koordinate des aktuellen Zeichenursprungs in 
   * Bezug auf den absoluten Ursprung
   * THREADSAFE
   * @see SimulationObject#getYOffset
   * @see SimulationObject#translate
   */

  public final int getXOffset() {
    offsetChangeLock.acquire();
    int returnValue = xOffset;
    offsetChangeLock.release();
    return returnValue;
  } // SimulationObject.getXOffset

  /**
   * Liefert die y-Koordinate des aktuellen Zeichenursprungs in 
   * Bezug auf den absoluten Ursprung
   * THREADSAFE
   * @see SimulationObject#getXOffset
   * @see SimulationObject#translate
   */

  public final int getYOffset() {
    offsetChangeLock.acquire();
    int returnValue = yOffset;
    offsetChangeLock.release();
    return returnValue;
    } // SimulationObject.getYOffset

  /** 
   * Liefert die Netzwerkkomponente, die sich an den übergebenen
   * Koordinate befindet
   * THREADSAFE
   * @see ArchitectureComponent
   */

  public final ArchitectureComponent getComponent( int x, int y ) {
    ArchitectureComponent component;
    int xpos, ypos, width, height;
    archChangeLock.acquire();
    for ( int i = archComponents.size() - 1; i >=0 ; i -= 1 ) {
      component = (ArchitectureComponent)archComponents.elementAt( i );
      if ( component.atLocation( x, y ) ) {
	archChangeLock.release();
	return component;
      } // if
    } // for
    archChangeLock.release();
    return (ArchitectureComponent) null;
  } // SimulationObject.getComponent

   /**
   * Liefert das Basis-Simulationsobjekt, d.h. Applet, Client oder Server
   * @see Simulation
   */

  public final Simulation getSimulation() {
    return simulation;
  } // SimulationObject.getSimulation
  
   
  /**
   * Liefert wahr, falls der Netzbetrieb beendet wurde
   */
  
  public final boolean isFinished() {
    return finished;
  } // SimulationObject.isFinished

} // SimulationObject


